package com.whitehot.klib.http.net;

/**
 * Created by yutf on 2017/9/5 0005.
 */

import com.google.gson.internal.$Gson$Types;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/***
 * 回调类，用于返回结果到前台，注意获取code的方法，以及验证返回是否成功的方法，根据需要覆盖
 *
 * @param <T> 传入一个泛型，会自动根据类型产生对象，在post中用处较多
 */
public abstract class ResultCallback<T extends Object>
{
    Type mType;

    public ResultCallback()
    {
        mType = getSuperclassTypeParameter(getClass(), 0);
    }

    public static Type getSuperclassTypeParameter(Class<?> subclass, int type)
    {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class)
        {
            throw new RuntimeException("ResultCallback泛型缺少对象类型");
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[type]);
    }

    public abstract void onError(String simpleMsg, int code,Exception e);

    /***
     * 根据外层JSONObject获取服务端错误信息，用于显示给用户
     * @param obj
     * @return
     */
    public String getServerFailedMessage(JSONObject obj) throws JSONException
    {
        return obj.getString("msg");
    }

    /***
     * 根据外层JSONObject获取服务端错误代码，用于对应作出处理
     * @param obj
     * @return
     */
    public int getServerCode(JSONObject obj) throws JSONException
    {
        return obj.getInt("CodeID");
    }

    /***
     * 是否需要对返回结果做判断，只有返回码正确是才解析数据。
     * 默认是返回false，即服务器返回了数据就按传入的对象类型解析。建议加入对返回值得判断
     */
    public boolean needVarifyResult() {return true;};


    public String getCodeKey()
    {
        return "code";
    }

    /***
     * 根据最外层的JSONObject判断返回码是否是正确的
     */
    public boolean isSuccess(JSONObject rawData) throws JSONException
    {
        if(rawData != null)
        {
            int codeId = rawData.getInt(getCodeKey());
            if(0 == codeId)
                return true;
        }
        return false;
    };

    /***
     * 下载回调
     * @param progress  进度
     * @param allLength 总长度
     * @param done       标注是否完成
     */
    public void onDownloadProgress(long progress, long allLength, boolean done){}

    /***
     * 上传回调
     * @param progress  进度
     * @param allLength 总长度
     * @param done       标注是否完成
     */
    public void onUploadProgress(long progress, long allLength, boolean done){}

    /***
     * 成功后回调
     * @param response
     */
    public abstract void onSuccess(T response);
}
